package corpo;

import excecoes.ValorDesconhecidoException;


/**
 * A classe Estabelecimento � respons�vel por gerenciar as informa��es relevantes (nome, endere�o e tipo de servi�o) de um estabelecimento para o reposit�rio do programa.
 * 
 * @author Pedro Augustus Diniz Falc�o Silva
 *
 */
public class Estabelecimento {
	
	public enum TipoDeServico {
		ALACARTE("A la carte"),
		PRATOFEITO("Prato feito"),
		SELFSERVICE("Self-service");
		
		private final String tipo;
		
		private TipoDeServico(String tipo) {
			this.tipo = tipo;
		}
		
		/**
		 * Retorna o tipo de servi�o em forma de String.
		 * @return O tipo de servi�o em forma de String.
		 */
		public String toString() {
			return tipo;
		}
		
		/**
		 * Compara a String passada como par�metro com cada tipo de servi�o pr�-definido no enum e retorna o Objeto TipoDeServico equivalente � String passada, caso exista. Em caso contr�rio, retorna uma exce��o TipoInvalidoException.
		 * @param tipo O tipo em forma de String.
		 * @return O Objeto que representa o tipo de servi�o passado em forma de String, se j� estiver pr�-definido na enumera��o.
		 * @throws TipoInvalidoException Caso nenhum dos valores pr�-definidos seja equivalente � String passada, em outras palavras, caso a String tenha sido escrita errada ou o tipo por ela descrito n�o esteja pr�-definido na enumera��o.
		 */
		public static TipoDeServico detectaTipo(String tipo) throws ValorDesconhecidoException {
			for (TipoDeServico t : TipoDeServico.values()) {
				if (t.toString().equals(tipo)) {
					return t;
				}
			} throw new ValorDesconhecidoException("O tipo passado como parametro nao foi reconhecido!");
		}
	}
	
	private String nome;
	private String endereco;
	private TipoDeServico tipoDeServico;
	
	public Estabelecimento(String nome, String endereco, TipoDeServico tipoDeServico) {
		this.nome = nome;
		this.endereco = endereco;
		this.tipoDeServico = tipoDeServico;
	}

	/**
	 * Altera o nome do estabelecimento.
	 * @param nome O novo nome para o estabelecimento.
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}
	
	/**
	 * Retorna o nome do estabelecimento.
	 * @return O nome do estabelecimento.
	 */
	public String getNome() {
		return nome;
	}
	
	/**
	 * Altera o endere�o do estabelecimento.
	 * @param endereco O novo endere�o do estabelecimento.
	 */
	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}
	/**
	 * Retorna o endere�o atual do estabelecimento.
	 * @return O endere�o.
	 */
	public String getEndereco() {
		return endereco;
	}
	
	/**
	 * Altera o modo como o estabelecimento serve os clientes.
	 * @param tipoDeServico O novo tipo de servico.
	 */
	public void setTipoDeServico(TipoDeServico tipoDeServico) {
		this.tipoDeServico = tipoDeServico;
	}
	
	/**
	 * Retorna um Objeto TipoDeServico que representa o modo como o estabelecimento serve os clientes em 'A la carte', 'Self-service' e 'Prato feito'.
	 * @return O tipo de servi�o do estabelecimento.
	 */
	public TipoDeServico getTipoDeServico() {
		return tipoDeServico;
	}
	
	@Override
	public String toString() {
		String pulaLinha = System.getProperties().getProperty("line.separator");
		String toString = "";
		
		toString = toString.concat(" == Estabelecimento == " + pulaLinha);
		toString = toString.concat(" Nome: " + this.getNome() + pulaLinha);
		toString = toString.concat(" Endereco: " + this.getEndereco() + pulaLinha);
		toString = toString.concat(" Tipo de servico: " + this.getTipoDeServico().toString() + pulaLinha);
		
		return toString;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((endereco == null) ? 0 : endereco.hashCode());
		result = prime * result + ((nome == null) ? 0 : nome.hashCode());
		result = prime * result + ((tipoDeServico == null) ? 0 : tipoDeServico.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Estabelecimento)) {
			return false;
		}
		Estabelecimento outro = (Estabelecimento) obj;
		if (endereco == null) {
			if (outro.endereco != null) {
				return false;
			}
		} else if (!endereco.equals(outro.endereco)) {
			return false;
		}
		if (nome == null) {
			if (outro.nome != null) {
				return false;
			}
		} else if (!nome.equals(outro.nome)) {
			return false;
		}
		if (tipoDeServico != outro.tipoDeServico) {
			return false;
		}
		return true;
	}
}
